{{tag>BROUILLON}}
====== Samba - Active Directory Domain Controller (AD DC) ======

Brouillon avant de compléter ou créer un nouvelle page concernant l'authentification d'un utilisateur avec Samba AD DC

La version actuelle se trouve ici [[:samba-active-directory|Samba - Active Directory Domain Controller (AD DC)]]
...

===== Versions =====
...
===== Installation de Samba=====
==== Paramètres généraux ====
Avant toute installation, il est nécessaire de définir son environnement. Ainsi, il sera possible de configurer correctement son serveur. Le reste de cette documentation se basera sur les paramètres suivants :

|Nom de domaine |example.com | \\ RFC 2606
|Royaume (realm) |EXAMPLE.COM |
|Nom de NetBIOS |example |
|Nom du serveur |ubndc01 |
|Adresse IP du serveur |192.168.1.11 |
|Rôle du serveur |DC (contrôleur de domaine) |
==== Pré-requis ====
...
==== Installation à partir des dépôts ====
...
==== Installation à partir des sources ====
...
===== Création d'un premier DC dans une nouvelle forêt =====
...
==== Initialisation de Samba ====
...
==== Démarrer Samba AD DC ====
...
===== Test de Samba AD DC =====
...
==== Tests des ACL ====
...
==== Tests des attributs étendus ====
...
==== Tests du DNS ====
...
==== Tests de Kerberos ====
...
==== Tests de SMB ====
...
===== Mise à jour depuis un domaine Samba de type NT4 vers un AD=====
...
===== Authentification avec Samba AD DC =====
Afin de réaliser l'authentification des utilisateurs d'AD, plusieurs méthodes existent :
  * [[https://wiki.samba.org/index.php/Local_user_management_and_authentication/sssd|sssd et pam_sss]]
  * [[https://wiki.samba.org/index.php/Local_user_management_and_authentication/nslcd|nslcd et pam_ldap]]
  * [[https://wiki.samba.org/index.php/Samba4/Winbind|winbind et pam_winbind]]
Seule cette dernière méthode est expliquée dans cette documentation.

==== Authentification des utilisateurs sur le DC avec //winbind// ====

=== Installation et configuration pour utiliser //winbind// ===
Les paquets suivants sont requis pour la mise en œuvre de cette authentification.
<code>sudo apt-get install libnss-winbind libpam-winbind winbind</code>

Il faut configurer le Name Service Switch (nsswitch) par l'ajout de winbind comme méthode pour les sections //passwd// et //group//.
Par exemple avec la commande :
<code>sudo sed -i '/^passwd:\|^group:/{ s/$/ winbind/; };' /etc/nsswitch.conf</code>
<file - /etc/nsswitch.conf>...
passwd: compat winbind
group:  compat winbind
...
</file>

Ceci permet de chercher et utiliser les utilisateurs, leurs mots de passes et les groupes venant de AD au travers de //winbind//.
Par défaut sur un DC, les commandes ci-dessous retourne la liste de tous les utilisateurs et groupes (y compris ceux d'AD). Ce comportement peut être modifié avec l'option //...// dans la partie global du fichier de configuration de samba (/etc/samba/smb.conf)
<code>getent passwd
getent group</code>

Les UID et GID, s'ils n'existent pas dans l'AD, sont automatiquement généré par winbind mais ils ne sont pas écrits dans AD par winbind. Cette remarque est importante car d'autres machines récupérant ces même informations de l'AD génèreront d'autres UID et GID pour un même utilisateur. Ceci crée une incohérance dans le domaine. Afin d'éviter ce problème, il est préférable de définir ces valeurs dans AD. Pour ce faire, il faut définir un range d'identifiant réservé uniquement pour AD, par exemple de 100000 à 999999. De plus, afin de garantir que seuls les utilisateurs et groupes possèdant un UID et GID dans AD puissent s'authentifier sur une machine Linux du domaine, il faut ajouter les options suivantes dans la partie globale du fichier de configuration de samba.
<file - /etc/samba/smb.conf>
...
   idmap config EXAMPLE:backend = ad
   idmap config EXAMPLE:schema_mode = rfc2307
   idmap config EXAMPLE:range = 100000-999999
   
   //?// winbind nss info = rfc2307 //?//
...
</file>

Création du home directory pour l'utilisateur du domaine.
<file - /usr/share/pam-configs/mkhomedir>
Default: no
Priority: 900
Session-Type: Additional
Session-Final:
        required        pam_mkhomedir.so skel=/etc/skel umask=0077 silent
</file>

Alternative en mofdifiant le fichier /usr/share/pam-config/winbind
<file - /usr/share/pam-config/winbind>...
Session:
        optional                        pam_winbind.so mkhomedir
...</file>

Un autre alternative consiste à monter le home directory de l'utilisateur lors du login. Une option du fichier de configuration /etc/samba/smb.conf est //homedir map = auto.home//. Ceci fait référence à autofs. Développement Ult.

Possibilité de limiter l'accès à un ou plusieurs groupes ou utilisateurs sur base du SID
Ajouter require_membership_of=SID à la fin de la ligne pam_winbind.so de la section Auth: du fichier /usr/share/pam-config/winbind
<file - /usr/share/pam-config/winbind>...
Auth:
        [success=end default=ignore]    pam_winbind.so krb5_auth krb5_ccache_type=FILE cached_login try_first_pass required_membership_of=S-1-5-21-5555555555-555555555-5555555555-512
...</file>
Le RID 512 représente le groupe //Domain Admins//

Activer cette nouvelle configuration :
<code>sudo pam-auth-update</code>

==== Générer les uidNumber et gidNumber dans l'AD ====
Le script suivant permet d'ajouter les uidNumber et gidNumber pour chaque utilisateur et chaque groupe de l'AD.
<note important>Ce script nécessite des droits élevés permettant d'écrite dans l'AD (p.ex. : root via la commande //sudo//). Une mauvaise exécution de ce script pourrait endommager AD ou faire perdre des données.</note>
<file bash uid-gid_master.sh>
#!/bin/bash

# Vérifier si ces valeurs existent dans smb.conf
# idmap config REALM:range = min-max
rangeMin=100000
rangeMax=999999

sam=/var/lib/samba/private/sam.ldb

createTmpDir() {
  tmpDir=$(mktemp -d --tmpdir addGid.XXXXXX) || exit 1
  tmpRecord=$tmpDir/record_
  tmpLdif=$tmpDir/ldif
}
cleanTmpDir() {
  rm $tmpDir/*
}
removeTmpDir() {
  rm -r $tmpDir
}
                                                                                                                                                                                              
findMaxId() {                                                                                                                                                                                 
  ldbsearch -H $sam "$regexp" $field | sed '/^# Referral/ { :loop; N; $! b loop; d; }; s/^\([a-zA-Z0-9]*\): \(.*\)$/\1="\2"/g; /^$/d;' | awk '/^# record/{n++}{print > f n}' f=$tmpRecord     
                                                                                                                                                                                              
  maxID=$rangeMin                                                                                                                                                                             
  for file in `grep -l -E "^$field=" ${tmpRecord}*`                                                                                                                                           
  do                                                                                                                                                                                          
    source $file                                                                                                                                                                              
    if [ ${!field} -gt $rangeMax ]
    then
      echo "Warning: $field ${!field} for $dn is bigger than max id $rangeMax" 1>&2
    elif [ ${!field} -lt $rangeMin ]
    then
      echo "Warning: $field ${!field} for $dn is lower than min id $rangeMin" 1>&2
    else
      [ ${!field} -gt $maxID ] && maxID=${!field}
    fi
  done

  echo "Max ID found for $field: $maxID"
}

addIdNumber() {
  for file in `grep -L -E "^$field=" ${tmpRecord}*`
  do
    ((maxID++))
    source $file
    echo "Adding $field: $maxID for dn: $dn"
    echo "dn: $dn
changetype: modify
add: $field
$field: $maxID" > $tmpLdif
    ldbmodify -H $sam $tmpLdif
  done
}

umask 0077
createTmpDir

field=uidNumber
regexp="(&(objectclass=user)(!(objectclass=computer)))"
findMaxId
addIdNumber
cleanTmpDir

field=gidNumber
regexp="(objectclass=group)"
findMaxId
addIdNumber
cleanTmpDir

removeTmpDir

exit 0
</file>


===== Informations optionnelles et complémentaires =====
...
===== Références =====
...
//Contributeurs principaux : [[utilisateurs:bcag2|bcag2]], [[:utilisateurs:Qedinux|Qedinux]]//